#include "Classifier.h"

#include "DataSet.h"
#include "Sample.h"

#include <iostream>

Classifier::Classifier() : nrClasses_(0)
{

}

Classifier::~Classifier()
{

}

void Classifier::experiment(const DataSet& ds,
                            float& accuracy,
                            const std::vector<std::string>& names,
                            const bool& verbose
                            ) const
{
  const unsigned int nrSamples = ds.samples().size();
  if (nrSamples <= 0 || ds.labels().size() != nrSamples || names.size() != nrSamples) {
    std::cerr << "Not enough samples." << std::endl;
    return;
  }

  // Init confusion matrix
  std::vector<std::vector<float> > confusionMatrix;
  confusionMatrix.resize(nrClasses_);
  for (unsigned int i = 0; i < nrClasses_; ++i) {
    confusionMatrix[i] = std::vector<float>(nrClasses_, 0.0);
  }

  // Classify all samples, update confusion matrix,
  // print messages (if verbose) and count errors.
  int errors = 0;
  for (unsigned int i = 0; i < nrSamples; ++i) {
    int c = test(ds.sample(i));
    int truth = ds.label(i);
    confusionMatrix[truth][c]++;

    if (truth != c) {
      ++errors;
      if (verbose) {
        std::cout << "Sample " << i << " (" << names[i] << ") is misclassified as class " << c << " instead of " << truth << std::endl;
      }
    }
  }

  // Compute accuracy
  accuracy = 1.0f - (float)errors / (float)nrSamples;
}